有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java基于Maven结果构建不同的Docker映像(与Jenkins一起)

我有一个Java应用程序,它有很多依赖项,我想将其拆分为多个Docker映像:

  • 具有代理(nginx)、JVM和数据库驱动程序的核心>;变化不大
  • 依赖项:我的应用程序所依赖的所有Jar文件->;有时会改变
  • 应用:一个额外的罐子->;每天或更多的更改(在开发期间)

大致如下:

Docker layers

我知道如何手动构建这些Docker映像。我还可以在maven中创建docker图像:

<plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>${dockerfile-maven-version}</version>
                <executions>
                    <execution>
                        <phase>pre-integration-test</phase>
                        <id>default</id>
                        <goals>
                            <goal>build</goal>
                            <goal>push</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <dockerfile>src/main/docker/dockerfile</dockerfile>
                    <repository>myprivateregistry.io:5000/repourl</repository>
                    <tag>${project.version}</tag>
                    <buildArgs>
                        <JAR_FILE>myapp.jar</JAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>

我想,我可以添加两次插件来构建中间层和顶层

但是,我只想启动中间构建,并且仅当包含所有依赖项Jar的target/libs的内容发生更改时(新Jar、新版本Jar、Jar删除)

我该怎么做

我们目前正在使用Jenkins来运行我们的构建(我倾向于使用“内部maven”解决方案)


共 (2) 个答案

  1. # 1 楼答案

    不幸的是,这在maven中是不可能的。 Maven不跟踪过去构建的模块,因此无法知道哪些LIB可能已经被修改。有像maven compiler plugin这样的插件,它会获取源文件的时间戳,并与类文件进行比较以跳过编译,但我怀疑是否有插件可以满足您的要求

    但是,总是按照您的建议构建两个图像。只需先构建依赖项映像,然后构建应用程序映像。Docker非常擅长缓存层。这意味着,如果LIB没有更改,它只会从缓存中检索图像。否则它将建立一个新的形象。重要提示:只有当Jenkins上的docker守护进程始终相同时,这才有效。如果你有一个集群Jenkins,将会有很多缓存未命中。但它在总体上仍然有效,但任何加速都会丢失

  2. # 2 楼答案

    事实证明,谷歌考虑到了这个问题,并为此创建了一个Maven插件。{a1}正是这样做的

    优点:它可以自动照顾所有层:

    • 资源
    • 依赖关系
    • 代码

    缺点:它不使用docker文件,而是在Maven POM中完全定义图像

    示例如下所示:

                        <plugin>
                            <groupId>com.google.cloud.tools</groupId>
                            <artifactId>jib-maven-plugin</artifactId>
                            <version>${jib.maven.plugin.version}</version>
                            <configuration>
                                <from>
                                    <image>some.base.image:latest</image>
                                </from>
                                <to>
                                    <image>destination.image</image>
                                    <tags>${project.version}</tags>
                                </to>
                                <extraDirectories>
                                    <paths>
                                        <path>
                                            <from>src/main/docker/scripts</from>
                                            <into>/opt/myapp/scripts</into>
                                        </path>
                                    </paths>
                                    <permissions>
                                        <permission>
                                            <file>/opt/shutdown_script</file>
                                            <mode>555</mode>
                                        </permission>
                                        <permission>
                                            <file>/opt/startup_script</file>
                                            <mode>555</mode>
                                        </permission>
                                    </permissions>
                                </extraDirectories>
                                <container>
                                    <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
                                    <appRoot>/opt/myapp</appRoot>
                                    <entrypoint>
                                        <entry>/opt/myapp/entry_point.sh</entry>
                                    </entrypoint>
                                    <ports>
                                        <port>80</port>
                                        <port>389</port>
                                        <port>8880</port>
                                        <port>8889</port>
                                        <port>8890</port>
                                    </ports>
                                    <user>appuser</user>
                                    <volumes>
                                        <volume>/local/data</volume>
                                    </volumes>
                                </container>
                            </configuration>
                            <executions>
                                <execution>
                                    <phase>package</phase>
                                    <goals>
                                        <goal>dockerBuild</goal>
                                    </goals>
                                </execution>
                            </executions>
                        </plugin>
    

    似乎适合我的需要